/**
 * @file 轨迹播放控制Hook
 * @description 提供轨迹播放器的控制逻辑，包括拖动处理、播放控制和范围选择等
 * @date 2024-08-21
 */

// @ts-ignore - uni-app环境下Vue导入需要忽略类型检查
import { ref, computed, watch, onMounted, onUnmounted, Ref } from 'vue';
import { useTrackAnimation } from './useTrackAnimation';
import { logger } from '@/utils/system/logger';

// 拖动类型定义
export type DragType = 'main' | 'rangeStart' | 'rangeEnd' | null;

// Hook配置类型
export interface TrackPlayerOptions {
  /** 是否自动播放 */
  autoPlay?: boolean;
  /** 是否启用范围选择 */
  enableRangeSelection?: boolean;
  /** 初始播放速度 */
  initialSpeed?: number;
}

/**
 * 根据百分比格式化时间
 * @param percentage 百分比值(0-100)
 * @returns 格式化后的时间字符串(HH:MM)
 */
export function formatTimeFromPercentage(percentage: number): string {
  // 假设一天24小时
  const totalMinutes = 24 * 60;
  const minutes = Math.floor((percentage / 100) * totalMinutes);
  const hours = Math.floor(minutes / 60);
  const mins = minutes % 60;
  return `${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}`;
}

/**
 * 从时间字符串中获取小时
 * @param timeString 时间字符串(HH:MM)
 * @returns 小时数值
 */
export function getHourFromTime(timeString: string): number {
  const [hours] = timeString.split(':').map(Number);
  return hours;
}

/**
 * 从时间字符串中获取分钟
 * @param timeString 时间字符串(HH:MM)
 * @returns 分钟数值
 */
export function getMinuteFromTime(timeString: string): number {
  const [, minutes] = timeString.split(':').map(Number);
  return minutes;
}

/**
 * 轨迹播放控制Hook
 * @param options Hook配置选项
 * @returns 轨迹播放控制相关方法和状态
 */
export function useTrackPlayer(options: TrackPlayerOptions = {}) {
  // 从useTrackAnimation获取播放控制方法
  const {
    trackLine,
    startAnimation,
    pauseAnimation,
  } = useTrackAnimation();
  
  // 播放控制状态
  const isPlaying = ref(false);
  const currentSpeed = ref(options.initialSpeed?.toString() || '1');
  
  // 进度控制
  const progressPercentage = ref(0);
  const currentTime = ref('00:00');
  
  // 拖动状态
  const isDragging = ref(false);
  const dragType = ref<DragType>(null);
  
  // 范围选择状态
  const showRangeSelection = ref(options.enableRangeSelection !== false);
  const startTimePercentage = ref(0);
  const endTimePercentage = ref(100);
  const formattedStartTime = ref('00:00');
  const formattedEndTime = ref('23:59');
  
  // 时间选择下拉框状态
  const showStartTimeDropdown = ref(false);
  const showEndTimeDropdown = ref(false);
  
  // 提示相关
  const tooltipTime = ref('');
  const timeTooltipStyle = ref({
    display: 'none',
    left: '0px'
  });
  
  // 计算属性 - 范围选择样式
  const rangeSelectionStyle = computed(() => ({
    left: startTimePercentage.value + '%',
    width: (endTimePercentage.value - startTimePercentage.value) + '%',
    display: showRangeSelection.value ? 'block' : 'none'
  }));
  
  // 开关样式
  const sliderStyle = computed(() => ({
    backgroundColor: showRangeSelection.value ? '#1890ff' : '#ccc',
    transition: 'background-color 0.4s'
  }));

  const sliderThumbStyle = computed(() => ({
    position: 'absolute',
    height: '16px',
    width: '16px',
    left: '3px',
    bottom: '3px',
    backgroundColor: 'white',
    borderRadius: '50%',
    transition: 'transform 0.4s',
    transform: showRangeSelection.value ? 'translateX(24px)' : 'translateX(0)'
  }));
  
  // 当前时间计算
  const formattedCurrentTime = computed(() => {
    return currentTime.value || formatTimeFromPercentage(progressPercentage.value);
  });
  
  /**
   * 切换播放/暂停状态
   */
  function togglePlay() {
    if (isPlaying.value) {
      pauseAnimation();
      isPlaying.value = false;
    } else {
      startAnimation();
      isPlaying.value = true;
    }
  }
  
  /**
   * 前进10分钟
   */
  function nextFrame() {
    progressPercentage.value = Math.min(100, progressPercentage.value + 5);
    // 通知轨迹图层进行位置更新
    if (trackLine.value && typeof trackLine.value.seekAndUpdate === 'function') {
      const totalPoints = trackLine.value.getNumPoints();
      if (totalPoints > 0) {
        const pointIndex = Math.floor((progressPercentage.value / 100) * totalPoints);
        trackLine.value.seekAndUpdate(pointIndex);
      }
    }
  }
  
  /**
   * 后退10分钟
   */
  function previousFrame() {
    progressPercentage.value = Math.max(0, progressPercentage.value - 5);
    // 通知轨迹图层进行位置更新
    if (trackLine.value && typeof trackLine.value.seekAndUpdate === 'function') {
      const totalPoints = trackLine.value.getNumPoints();
      if (totalPoints > 0) {
        const pointIndex = Math.floor((progressPercentage.value / 100) * totalPoints);
        trackLine.value.seekAndUpdate(pointIndex);
      }
    }
  }
  
  /**
   * 改变播放速度
   */
  function changeSpeed() {
    const speed = parseFloat(currentSpeed.value);
    // 如果轨迹图层存在，调用相应方法
    if (trackLine.value && typeof trackLine.value.setSpeedMode === 'function') {
      trackLine.value.setSpeedMode(speed);
    }
  }
  
  /**
   * 判断是否是当前小时
   */
  function isCurrentHour(hour: number): boolean {
    // 根据当前进度计算当前小时
    const currentHour = Math.floor((progressPercentage.value / 100) * 24);
    return hour === currentHour;
  }
  
  /**
   * 跳转到指定位置
   * @param event 鼠标事件
   */
  function seekToPosition(event: MouseEvent): void {
    // 如果正在拖动，不处理点击事件
    if (isDragging.value) return;
    
    const timeline = event.currentTarget as HTMLElement;
    const rect = timeline.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));
    
    // 更新进度并通知轨迹图层
    updateProgress(percentage);
    
    // 显示提示
    tooltipTime.value = formatTimeFromPercentage(percentage);
    timeTooltipStyle.value = {
      display: 'block',
      left: `${x}px`
    };
    
    // 3秒后隐藏提示
    setTimeout(() => {
      timeTooltipStyle.value.display = 'none';
    }, 3000);
  }
  
  /**
   * 触摸时跳转到指定位置
   * @param event 触摸事件
   */
  function seekToPositionTouch(event: TouchEvent): void {
    // 如果正在拖动，不处理点击事件
    if (isDragging.value) return;
    
    const touch = event.touches[0];
    const timeline = event.currentTarget as HTMLElement;
    const rect = timeline.getBoundingClientRect();
    const x = touch.clientX - rect.left;
    const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));
    
    // 更新进度并通知轨迹图层
    updateProgress(percentage);
    
    // 显示提示
    tooltipTime.value = formatTimeFromPercentage(percentage);
    timeTooltipStyle.value = {
      display: 'block',
      left: `${x}px`
    };
    
    // 3秒后隐藏提示
    setTimeout(() => {
      timeTooltipStyle.value.display = 'none';
    }, 3000);
  }
  
  /**
   * 更新进度并通知外部
   * @param percentage 进度百分比
   */
  function updateProgress(percentage: number): void {
    progressPercentage.value = percentage;
    if (trackLine.value && typeof trackLine.value.seekAndUpdate === 'function') {
      const totalPoints = trackLine.value.getNumPoints?.();
      if (totalPoints > 0) {
        const pointIndex = Math.floor((percentage / 100) * totalPoints);
        trackLine.value.seekAndUpdate(pointIndex);
      }
    }
  }
  
  /**
   * 开始拖动
   * @param event 鼠标事件
   * @param type 拖动类型
   */
  function startDrag(event: MouseEvent, type: DragType): void {
    event.stopPropagation();
    event.preventDefault();
    
    isDragging.value = true;
    dragType.value = type;
    
    // 显示提示
    const target = event.currentTarget as HTMLElement;
    let tooltipValue = '';
    
    switch (type) {
      case 'main':
        tooltipValue = formatTimeFromPercentage(progressPercentage.value);
        break;
      case 'rangeStart':
        tooltipValue = formatTimeFromPercentage(startTimePercentage.value);
        break;
      case 'rangeEnd':
        tooltipValue = formatTimeFromPercentage(endTimePercentage.value);
        break;
    }
    
    // 显示提示
    tooltipTime.value = tooltipValue;
    const rect = target.getBoundingClientRect();
    const timelineRect = (target.parentElement as HTMLElement).getBoundingClientRect();
    const left = rect.left - timelineRect.left + (target.offsetWidth / 2);
    timeTooltipStyle.value = {
      display: 'block',
      left: `${left}px`
    };
    
    // 添加鼠标移动和抬起事件
    document.addEventListener('mousemove', handleDrag);
    document.addEventListener('mouseup', stopDrag);
    
    // 防止拖动时选中文本
    document.addEventListener('selectstart', preventTextSelection);
  }
  
  /**
   * 开始触摸拖动
   * @param event 触摸事件
   * @param type 拖动类型
   */
  function startDragTouch(event: TouchEvent, type: DragType): void {
    event.stopPropagation();
    event.preventDefault();
    
    isDragging.value = true;
    dragType.value = type;
    
    // 显示提示
    const target = event.currentTarget as HTMLElement;
    let tooltipValue = '';
    
    switch (type) {
      case 'main':
        tooltipValue = formatTimeFromPercentage(progressPercentage.value);
        break;
      case 'rangeStart':
        tooltipValue = formatTimeFromPercentage(startTimePercentage.value);
        break;
      case 'rangeEnd':
        tooltipValue = formatTimeFromPercentage(endTimePercentage.value);
        break;
    }
    
    // 显示提示
    tooltipTime.value = tooltipValue;
    const rect = target.getBoundingClientRect();
    const timelineRect = (target.parentElement as HTMLElement).getBoundingClientRect();
    const left = rect.left - timelineRect.left + (target.offsetWidth / 2);
    timeTooltipStyle.value = {
      display: 'block',
      left: `${left}px`
    };
    
    // 添加触摸移动和结束事件
    document.addEventListener('touchmove', handleDragTouch, { passive: false });
    document.addEventListener('touchend', stopDragTouch);
  }
  
  /**
   * 处理拖动
   * @param event 鼠标事件
   */
  function handleDrag(event: MouseEvent): void {
    if (!isDragging.value) return;
    
    event.preventDefault();
    
    // 获取时间轴元素
    const timeline = document.querySelector('.timeline') as HTMLElement;
    if (!timeline) return;
    
    const rect = timeline.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));
    
    // 更新相应元素
    updateDragPosition(percentage, timeline);
  }
  
  /**
   * 处理触摸拖动
   * @param event 触摸事件
   */
  function handleDragTouch(event: TouchEvent): void {
    if (!isDragging.value) return;
    
    event.preventDefault();
    
    // 获取触摸点
    const touch = event.touches[0];
    
    // 获取时间轴元素
    const timeline = document.querySelector('.timeline') as HTMLElement;
    if (!timeline) return;
    
    const rect = timeline.getBoundingClientRect();
    const x = touch.clientX - rect.left;
    const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));
    
    // 更新相应元素
    updateDragPosition(percentage, timeline);
  }
  
  /**
   * 更新拖动位置
   * @param percentage 百分比位置
   * @param timeline 时间轴元素
   */
  function updateDragPosition(percentage: number, timeline: HTMLElement): void {
    // 更新相应元素
    switch (dragType.value) {
      case 'main':
        progressPercentage.value = percentage;
        tooltipTime.value = formatTimeFromPercentage(percentage);
        // 通知轨迹图层进行位置更新
        if (trackLine.value && typeof trackLine.value.seekAndUpdate === 'function') {
          const totalPoints = trackLine.value.getNumPoints?.();
          if (totalPoints > 0) {
            const pointIndex = Math.floor((percentage / 100) * totalPoints);
            trackLine.value.seekAndUpdate(pointIndex);
          }
        }
        break;
      case 'rangeStart':
        // 确保开始时间不超过结束时间减去最小间隔(1分钟)
        const minDistancePercentage = (1 / (24 * 60)) * 100; // 1分钟占总时长的百分比
        const maxStartPercentage = endTimePercentage.value - minDistancePercentage;
        
        // 限制开始时间百分比在有效范围内
        startTimePercentage.value = Math.min(Math.max(0, percentage), maxStartPercentage);
        tooltipTime.value = formatTimeFromPercentage(startTimePercentage.value);
        
        // 更新开始时间显示
        const [startHours, startMinutes] = formatTimeFromPercentage(startTimePercentage.value).split(':');
        formattedStartTime.value = `${startHours}:${startMinutes}`;
        break;
      case 'rangeEnd':
        // 确保结束时间不小于开始时间加上最小间隔(1分钟)
        const minEndDistancePercentage = (1 / (24 * 60)) * 100; // 1分钟占总时长的百分比
        const minEndPercentage = startTimePercentage.value + minEndDistancePercentage;
        
        // 限制结束时间百分比在有效范围内
        endTimePercentage.value = Math.max(Math.min(100, percentage), minEndPercentage);
        tooltipTime.value = formatTimeFromPercentage(endTimePercentage.value);
        
        // 更新结束时间显示
        const [endHours, endMinutes] = formatTimeFromPercentage(endTimePercentage.value).split(':');
        formattedEndTime.value = `${endHours}:${endMinutes}`;
        break;
    }
    
    // 更新提示位置
    const targetElement = document.querySelector(
      dragType.value === 'main' ? '.timeline-handle' :
      dragType.value === 'rangeStart' ? '.range-handle.start' :
      '.range-handle.end'
    ) as HTMLElement;
    
    if (targetElement) {
      const elementRect = targetElement.getBoundingClientRect();
      const timelineRect = timeline.getBoundingClientRect();
      const left = elementRect.left - timelineRect.left + (targetElement.offsetWidth / 2);
      timeTooltipStyle.value.left = `${left}px`;
    }
  }
  
  /**
   * 停止拖动
   */
  function stopDrag(): void {
    if (!isDragging.value) return;
    
    isDragging.value = false;
    
    // 根据拖动类型来处理完成事件
    if (dragType.value === 'rangeStart' || dragType.value === 'rangeEnd') {
      // 范围变更结束，发送事件
      emitRangeChangeEvent();
    }
    
    dragType.value = null;
    
    // 隐藏提示
    timeTooltipStyle.value.display = 'none';
    
    // 移除事件监听
    document.removeEventListener('mousemove', handleDrag);
    document.removeEventListener('mouseup', stopDrag);
    document.removeEventListener('selectstart', preventTextSelection);
  }
  
  /**
   * 停止触摸拖动
   */
  function stopDragTouch(): void {
    if (!isDragging.value) return;
    
    isDragging.value = false;
    
    // 根据拖动类型来处理完成事件
    if (dragType.value === 'rangeStart' || dragType.value === 'rangeEnd') {
      // 范围变更结束，发送事件
      emitRangeChangeEvent();
    }
    
    dragType.value = null;
    
    // 隐藏提示
    timeTooltipStyle.value.display = 'none';
    
    // 移除事件监听
    document.removeEventListener('touchmove', handleDragTouch);
    document.removeEventListener('touchend', stopDragTouch);
  }
  
  /**
   * 阻止文本选择
   * @param event 事件对象
   */
  function preventTextSelection(event: Event): void {
    if (isDragging.value) event.preventDefault();
  }
  
  /**
   * 切换开始时间下拉框
   * @param event 事件对象
   */
  function toggleStartTimeDropdown(event: Event): void {
    event.stopPropagation();
    showStartTimeDropdown.value = !showStartTimeDropdown.value;
    
    // 关闭另一个下拉框
    if (showStartTimeDropdown.value) {
      showEndTimeDropdown.value = false;
      
      // 添加点击外部关闭下拉框的事件
      setTimeout(() => {
        document.addEventListener('click', closeStartTimeDropdown);
      }, 0);
    }
  }
  
  /**
   * 关闭开始时间下拉框
   */
  function closeStartTimeDropdown(): void {
    showStartTimeDropdown.value = false;
    document.removeEventListener('click', closeStartTimeDropdown);
  }
  
  /**
   * 切换结束时间下拉框
   * @param event 事件对象
   */
  function toggleEndTimeDropdown(event: Event): void {
    event.stopPropagation();
    showEndTimeDropdown.value = !showEndTimeDropdown.value;
    
    // 关闭另一个下拉框
    if (showEndTimeDropdown.value) {
      showStartTimeDropdown.value = false;
      
      // 添加点击外部关闭下拉框的事件
      setTimeout(() => {
        document.addEventListener('click', closeEndTimeDropdown);
      }, 0);
    }
  }
  
  /**
   * 关闭结束时间下拉框
   */
  function closeEndTimeDropdown(): void {
    showEndTimeDropdown.value = false;
    document.removeEventListener('click', closeEndTimeDropdown);
  }
  
  /**
   * 选择开始时间的小时
   * @param hour 小时值
   */
  function selectStartHour(hour: number): void {
    const [, minutes] = formattedStartTime.value.split(':');
    const newStartTime = `${String(hour).padStart(2, '0')}:${minutes}`;
    
    // 验证选择的时间是否有效
    const startTotalMinutes = hour * 60 + parseInt(minutes);
    const [endHours, endMinutes] = formattedEndTime.value.split(':').map(Number);
    const endTotalMinutes = endHours * 60 + endMinutes;
    
    // 最小时间差为1分钟
    const minTimeDifference = 1;
    
    if (startTotalMinutes >= endTotalMinutes - minTimeDifference) {
      // 如果开始时间太接近或晚于结束时间，不更新
      return;
    }
    
    formattedStartTime.value = newStartTime;
    updateStartTimePercentage();
  }
  
  /**
   * 选择开始时间的分钟
   * @param minute 分钟值
   */
  function selectStartMinute(minute: number): void {
    const [hours] = formattedStartTime.value.split(':');
    const newStartTime = `${hours}:${String(minute).padStart(2, '0')}`;
    
    // 验证选择的时间是否有效
    const startTotalMinutes = parseInt(hours) * 60 + minute;
    const [endHours, endMinutes] = formattedEndTime.value.split(':').map(Number);
    const endTotalMinutes = endHours * 60 + endMinutes;
    
    // 最小时间差为1分钟
    const minTimeDifference = 1;
    
    if (startTotalMinutes >= endTotalMinutes - minTimeDifference) {
      // 如果开始时间太接近或晚于结束时间，不更新
      closeStartTimeDropdown();
      return;
    }
    
    formattedStartTime.value = newStartTime;
    updateStartTimePercentage();
    closeStartTimeDropdown();
  }
  
  /**
   * 选择结束时间的小时
   * @param hour 小时值
   */
  function selectEndHour(hour: number): void {
    const [, minutes] = formattedEndTime.value.split(':');
    const newEndTime = `${String(hour).padStart(2, '0')}:${minutes}`;
    
    // 验证选择的时间是否有效
    const [startHours, startMinutes] = formattedStartTime.value.split(':').map(Number);
    const startTotalMinutes = startHours * 60 + startMinutes;
    const endTotalMinutes = hour * 60 + parseInt(minutes);
    
    // 最小时间差为1分钟
    const minTimeDifference = 1;
    
    if (endTotalMinutes <= startTotalMinutes + minTimeDifference) {
      // 如果结束时间太接近或早于开始时间，不更新
      return;
    }
    
    formattedEndTime.value = newEndTime;
    updateEndTimePercentage();
  }
  
  /**
   * 选择结束时间的分钟
   * @param minute 分钟值
   */
  function selectEndMinute(minute: number): void {
    const [hours] = formattedEndTime.value.split(':');
    const newEndTime = `${hours}:${String(minute).padStart(2, '0')}`;
    
    // 验证选择的时间是否有效
    const [startHours, startMinutes] = formattedStartTime.value.split(':').map(Number);
    const startTotalMinutes = startHours * 60 + startMinutes;
    const endTotalMinutes = parseInt(hours) * 60 + minute;
    
    // 最小时间差为1分钟
    const minTimeDifference = 1;
    
    if (endTotalMinutes <= startTotalMinutes + minTimeDifference) {
      // 如果结束时间太接近或早于开始时间，不更新
      closeEndTimeDropdown();
      return;
    }
    
    formattedEndTime.value = newEndTime;
    updateEndTimePercentage();
    closeEndTimeDropdown();
  }
  
  /**
   * 更新开始时间百分比
   */
  function updateStartTimePercentage(time?: string) {
    const timeStr = time || formattedStartTime.value;
    const hour = parseInt(timeStr.split(':')[0]);
    const minute = parseInt(timeStr.split(':')[1]);
    
    // 计算总分钟数
    const totalMinutes = hour * 60 + minute;
    
    // 转换为百分比 (一天总共24*60=1440分钟)
    startTimePercentage.value = (totalMinutes / 1440) * 100;
    
    // 更新范围样式
    rangeSelectionStyle.value = {
      left: `${startTimePercentage.value}%`,
      width: `${endTimePercentage.value - startTimePercentage.value}%`
    };
    
    return startTimePercentage.value;
  }
  
  /**
   * 更新结束时间百分比
   */
  function updateEndTimePercentage(time?: string) {
    const timeStr = time || formattedEndTime.value;
    const hour = parseInt(timeStr.split(':')[0]);
    const minute = parseInt(timeStr.split(':')[1]);
    
    // 计算总分钟数
    const totalMinutes = hour * 60 + minute;
    
    // 转换为百分比 (一天总共24*60=1440分钟)
    endTimePercentage.value = (totalMinutes / 1440) * 100;
    
    // 更新范围样式
    rangeSelectionStyle.value = {
      left: `${startTimePercentage.value}%`,
      width: `${endTimePercentage.value - startTimePercentage.value}%`
    };
    
    return endTimePercentage.value;
  }
  
  /**
   * 发送范围变化事件
   * 这个函数在外部实现中被具体的event emit替换
   */
  function emitRangeChangeEvent(): void {
    logger.info('范围变更', {
      component: 'TrackPlayer',
      start: startTimePercentage.value,
      end: endTimePercentage.value
    });
  }
  
  /**
   * 切换显示范围
   */
  function toggleRangeDisplay(): void {
    showRangeSelection.value = !showRangeSelection.value;
    logger.info('切换显示范围', { 
      component: 'TrackPlayer',
      showRange: showRangeSelection.value
    });
  }
  
  /**
   * 点击显示范围容器
   */
  function clickToggleRange(): void {
    toggleRangeDisplay();
  }
  
  /**
   * 处理范围切换
   * @param event 事件对象
   */
  function handleRangeToggle(event: Event): void {
    const target = event.target as HTMLInputElement;
    showRangeSelection.value = target.checked;
    // 这里外部实现会发送事件
    logger.info('范围显示状态变更', { 
      component: 'TrackPlayer',
      showRange: showRangeSelection.value
    });
  }
  
  /**
   * 初始化时间百分比
   */
  function initTimePercentages(): void {
    // 初始化时间百分比
    updateStartTimePercentage();
    updateEndTimePercentage();
  }
  
  // 组件挂载时的初始化
  onMounted(() => {
    initTimePercentages();
  });
  
  // 组件卸载时清理事件监听
  onUnmounted(() => {
    // 清理可能存在的事件监听
    document.removeEventListener('mousemove', handleDrag);
    document.removeEventListener('mouseup', stopDrag);
    document.removeEventListener('touchmove', handleDragTouch);
    document.removeEventListener('touchend', stopDragTouch);
    document.removeEventListener('selectstart', preventTextSelection);
    document.removeEventListener('click', closeStartTimeDropdown);
    document.removeEventListener('click', closeEndTimeDropdown);
  });
  
  // 返回方法和状态
  return {
    // 状态
    isPlaying,
    currentSpeed,
    progressPercentage,
    currentTime,
    formattedCurrentTime,
    
    // 拖动状态
    isDragging,
    dragType,
    
    // 范围选择状态
    showRangeSelection,
    startTimePercentage,
    endTimePercentage,
    formattedStartTime,
    formattedEndTime,
    rangeSelectionStyle,
    
    // 下拉框状态
    showStartTimeDropdown,
    showEndTimeDropdown,
    
    // 提示相关
    tooltipTime,
    timeTooltipStyle,
    
    // 样式对象
    sliderStyle,
    sliderThumbStyle,
    
    // 方法 - 播放控制
    togglePlay,
    nextFrame,
    previousFrame,
    changeSpeed,
    isCurrentHour,
    
    // 方法 - 跳转
    seekToPosition,
    seekToPositionTouch,
    updateProgress,
    
    // 方法 - 拖动
    startDrag,
    startDragTouch,
    handleDrag,
    handleDragTouch,
    stopDrag,
    stopDragTouch,
    
    // 方法 - 时间选择
    toggleStartTimeDropdown,
    toggleEndTimeDropdown,
    closeStartTimeDropdown,
    closeEndTimeDropdown,
    selectStartHour,
    selectStartMinute,
    selectEndHour,
    selectEndMinute,
    
    // 方法 - 范围控制
    updateStartTimePercentage,
    updateEndTimePercentage,
    toggleRangeDisplay,
    clickToggleRange,
    handleRangeToggle,
    
    // 帮助方法
    formatTimeFromPercentage,
    preventTextSelection,
    initTimePercentages
  };
} 